<template>
  <div class="comments-section">
    <div class="comments-header">
      <div class="comments-title">
        <span>{{ totalComments }}条评论</span>
      </div>
      <div class="comments-actions">
        <el-button 
          type="text"
          size="small"
          @click="refresh"
        >
          <i class="el-icon-refresh"></i> 刷新
        </el-button>
        <el-select 
          v-model="sortType" 
          size="small"
          placeholder="排序方式"
          style="width: 100px"
        >
          <el-option label="最新" value="newest"></el-option>
          <el-option label="最早" value="oldest"></el-option>
          <el-option label="点赞数" value="votes"></el-option>
        </el-select>
      </div>
    </div>
    
    <div v-if="loading" class="comments-loading">
      <el-skeleton :rows="3" animated />
    </div>
    
    <div v-else-if="comments.length === 0" class="no-comments">
      <el-empty description="暂无评论" :image-size="80">
        <span>来发表第一条评论吧</span>
      </el-empty>
    </div>
    
    <div v-else class="comments-list">
      <transition-group name="comment-list" tag="div">
        <div v-for="comment in sortedComments" :key="comment.id" class="comment-item">
          <div class="comment-avatar">
            <el-avatar :src="comment.avatar || defaultAvatar" :size="36"></el-avatar>
          </div>
          
          <div class="comment-content">
            <div class="comment-header">
              <div class="comment-author">{{ comment.nickname || comment.username }}</div>
              <div class="comment-time">{{ formatTime(comment.createTime) }}</div>
            </div>
            
            <div class="comment-body" v-if="!editingComment || editingComment.id !== comment.id">
              {{ comment.content }}
            </div>
            
            <div v-else class="comment-edit">
              <el-input 
                v-model="editForm.content"
                type="textarea"
                :rows="2"
                placeholder="请输入评论内容"
                maxlength="500"
                show-word-limit
              ></el-input>
              <div class="edit-actions">
                <el-button size="small" @click="cancelEdit">取消</el-button>
                <el-button type="primary" size="small" @click="submitEdit">保存</el-button>
              </div>
            </div>
            
            <div class="comment-footer">
              <div class="comment-actions">
                <!-- 点赞按钮 -->
                <div class="vote-button" :class="{'voted': comment.voteStatus === 1}" @click="handleVote(comment)">
                  <i :class="comment.voteStatus === 1 ? 'el-icon-star-on' : 'el-icon-star-off'"></i>
                  <span class="vote-count">{{ comment.voteCount || 0 }}</span>
                </div>
                
                <el-button type="text" size="small" class="action-btn" @click="replyTo(comment)">
                  <i class="el-icon-chat-dot-round"></i> 回复
                </el-button>
                
                <template v-if="canManageComment(comment)">
                  <el-button type="text" size="small" class="action-btn" @click="editComment(comment)">
                    <i class="el-icon-edit"></i> 编辑
                  </el-button>
                  <el-button type="text" size="small" class="action-btn" @click="deleteComment(comment.id)">
                    <i class="el-icon-delete"></i> 删除
                  </el-button>
                </template>
              </div>
            </div>
          </div>
        </div>
      </transition-group>
      
      <div v-if="hasMore" class="load-more">
        <el-button type="text" :loading="loadingMore" @click="loadMore">加载更多</el-button>
      </div>
    </div>
    
    <div class="add-comment">
      <div class="comment-input-header">
        <span v-if="replyingTo">
          回复 <strong>{{ replyingTo.nickname || replyingTo.username }}</strong>
          <el-button type="text" size="small" @click="cancelReply">取消</el-button>
        </span>
        <span v-else>发表评论</span>
      </div>
      
      <div class="comment-input-body">
        <el-input
          v-model="newComment"
          type="textarea"
          :rows="2"
          placeholder="请输入评论内容..."
          maxlength="500"
          show-word-limit
        ></el-input>
      </div>
      
      <div class="comment-input-footer">
        <el-button 
          type="primary"
          size="small"
          :loading="submitting"
          :disabled="!newComment.trim()"
          @click="submitComment"
        >
          发表评论
        </el-button>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, computed, onMounted, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { createComment, getComments, updateComment, deleteComment } from '../api/comment'
import { voteComment, cancelVoteComment, checkCommentVoteStatus } from '../api/comment'

export default {
  name: 'CommentList',
  props: {
    answerId: {
      type: Number,
      required: true
    }
  },
  emits: ['update:count'],
  setup(props, { emit }) {
    // 评论数据相关
    const comments = ref([])
    const commentCache = ref({}) // 缓存评论数据，防止数据丢失
    const loading = ref(false)
    const loadingMore = ref(false)
    const currentPage = ref(1)
    const pageSize = ref(10)
    const total = ref(0)
    const sortType = ref('newest')
    const defaultAvatar = 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'
    
    // 评论操作相关
    const newComment = ref('')
    const submitting = ref(false)
    const replyingTo = ref(null)
    const editingComment = ref(null)
    const editForm = ref({ content: '' })
    
    // 计算属性
    const hasMore = computed(() => {
      return comments.value.length < total.value
    })
    
    const totalComments = computed(() => {
      return total.value
    })
    
    const sortedComments = computed(() => {
      if (sortType.value === 'oldest') {
        return [...comments.value].sort((a, b) => new Date(a.createTime) - new Date(b.createTime))
      } else if (sortType.value === 'votes') {
        return [...comments.value].sort((a, b) => (b.voteCount || 0) - (a.voteCount || 0))
      } else {
        return [...comments.value].sort((a, b) => new Date(b.createTime) - new Date(a.createTime))
      }
    })
    
    // 监听排序方式变化
    watch(sortType, () => {
      // 只重新排序，不需要重新获取数据
      // 除非是首次加载或者需要按点赞数排序且未加载过
      if (sortType.value === 'votes' && !comments.value.some(c => c.voteStatus !== undefined)) {
        refresh()
      }
    })
    
    // 加载评论列表
    const fetchComments = async (isLoadMore = false) => {
      try {
        if (isLoadMore) {
          loadingMore.value = true
        } else {
          loading.value = true
          // 重置页码，但保留缓存数据
          currentPage.value = 1
          // 只在全新加载时清空评论
          if (Object.keys(commentCache.value).length === 0) {
            comments.value = []
          }
        }
        
        const params = {
          current: currentPage.value,
          size: pageSize.value
        }
        
        const res = await getComments(props.answerId, params)
        
        if (res && res.data) {
          const commentList = res.data.records || []
          
          // 处理新获取的评论数据
          commentList.forEach(comment => {
            // 使用缓存数据补充点赞状态等信息
            if (commentCache.value[comment.id]) {
              comment.voteStatus = commentCache.value[comment.id].voteStatus
              comment.voteCount = commentCache.value[comment.id].voteCount
            }
            // 更新缓存
            commentCache.value[comment.id] = { ...comment }
          })
          
          if (isLoadMore) {
            // 合并新旧数据，避免重复
            const newComments = commentList.filter(comment => 
              !comments.value.some(c => c.id === comment.id)
            )
            comments.value = [...comments.value, ...newComments]
          } else {
            comments.value = commentList
          }
          
          // 检查并加载评论的点赞状态
          loadVoteStatus(commentList)
          
          total.value = res.data.total || 0
          emit('update:count', total.value)
        }
      } catch (error) {
        console.error('获取评论失败:', error)
        ElMessage.error('获取评论失败，请稍后重试')
      } finally {
        loading.value = false
        loadingMore.value = false
      }
    }
    
    // 加载评论点赞状态
    const loadVoteStatus = async (commentList) => {
      try {
        const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
        // 只有登录用户才需要获取点赞状态
        if (!userInfo.id) return
        
        // 获取点赞状态
        for (const comment of commentList) {
          try {
            const res = await checkCommentVoteStatus(comment.id)
            if (res && res.data !== undefined) {
              // 更新评论的点赞状态
              comment.voteStatus = res.data
              // 同时更新缓存
              if (commentCache.value[comment.id]) {
                commentCache.value[comment.id].voteStatus = res.data
              }
            }
          } catch (e) {
            console.error(`获取评论${comment.id}点赞状态失败:`, e)
          }
        }
      } catch (error) {
        console.error('获取评论点赞状态失败:', error)
      }
    }
    
    // 加载更多评论
    const loadMore = async () => {
      if (loadingMore.value || !hasMore.value) return
      
      currentPage.value++
      await fetchComments(true)
    }
    
    // 刷新评论
    const refresh = () => {
      fetchComments()
    }
    
    // 格式化时间
    const formatTime = (timestamp) => {
      if (!timestamp) return ''
      
      const now = new Date()
      const date = new Date(timestamp)
      const diff = Math.floor((now - date) / 1000) // 时间差（秒）
      
      if (diff < 60) {
        return `${diff}秒前`
      } else if (diff < 3600) {
        return `${Math.floor(diff / 60)}分钟前`
      } else if (diff < 86400) {
        return `${Math.floor(diff / 3600)}小时前`
      } else if (diff < 604800) {
        return `${Math.floor(diff / 86400)}天前`
      } else {
        return date.toLocaleDateString()
      }
    }
    
    // 点赞评论
    const handleVote = async (comment) => {
      try {
        const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
        if (!userInfo.id) {
          ElMessage.warning('请先登录后再点赞')
          return
        }
        
        // 如果已经点赞，则取消点赞
        if (comment.voteStatus === 1) {
          await cancelVoteComment(comment.id)
          comment.voteStatus = 0
          comment.voteCount = Math.max(0, (comment.voteCount || 1) - 1)
        } else {
          // 否则点赞
          await voteComment({ commentId: comment.id, voteType: 1 })
          comment.voteStatus = 1
          comment.voteCount = (comment.voteCount || 0) + 1
        }
        
        // 更新缓存数据
        if (commentCache.value[comment.id]) {
          commentCache.value[comment.id].voteStatus = comment.voteStatus
          commentCache.value[comment.id].voteCount = comment.voteCount
        }
      } catch (error) {
        console.error('评论点赞操作失败:', error)
        ElMessage.error('点赞失败，请稍后重试')
      }
    }
    
    // 提交评论
    const submitComment = async () => {
      if (!newComment.value.trim()) {
        ElMessage.warning('评论内容不能为空')
        return
      }
      
      try {
        submitting.value = true
        
        // 构建评论数据
        const commentData = {
          answerId: props.answerId,
          content: newComment.value
        }
        
        // 添加回复关系（如果有）
        if (replyingTo.value) {
          commentData.replyToId = replyingTo.value.id
          commentData.replyToUser = replyingTo.value.userId
        }
        
        // 发送请求
        const result = await createComment(commentData)
        
        if (result && result.code === 200 && result.data) {
          // 将新评论添加到列表
          const newCommentData = result.data
          // 设置默认值
          newCommentData.voteCount = 0
          newCommentData.voteStatus = 0
          
          // 如果是按最新排序，直接添加到前面
          if (sortType.value !== 'oldest') {
            comments.value.unshift(newCommentData)
          } else {
            comments.value.push(newCommentData)
          }
          
          // 更新缓存
          commentCache.value[newCommentData.id] = { ...newCommentData }
          
          // 更新总数
          total.value++
          emit('update:count', total.value)
          
          // 清空输入框
          newComment.value = ''
          replyingTo.value = null
          
          ElMessage.success('评论发表成功')
        } else {
          throw new Error(result?.message || '评论发表失败')
        }
      } catch (error) {
        console.error('发表评论失败:', error)
        ElMessage.error('发表评论失败，请稍后重试')
      } finally {
        submitting.value = false
      }
    }
    
    // 回复评论
    const replyTo = (comment) => {
      replyingTo.value = comment
      newComment.value = `@${comment.nickname || comment.username} `
      // 聚焦输入框
      setTimeout(() => {
        document.querySelector('.add-comment .el-textarea__inner').focus()
      }, 100)
    }
    
    // 取消回复
    const cancelReply = () => {
      replyingTo.value = null
      newComment.value = ''
    }
    
    // 编辑评论
    const editComment = (comment) => {
      editingComment.value = comment
      editForm.value.content = comment.content
    }
    
    // 取消编辑
    const cancelEdit = () => {
      editingComment.value = null
      editForm.value.content = ''
    }
    
    // 提交编辑
    const submitEdit = async () => {
      if (!editForm.value.content.trim()) {
        ElMessage.warning('评论内容不能为空')
        return
      }
      
      try {
        // 发送更新请求
        const result = await updateComment(editingComment.value.id, {
          answerId: props.answerId,
          content: editForm.value.content
        })
        
        if (result && result.code === 200) {
          // 更新本地数据
          const index = comments.value.findIndex(item => item.id === editingComment.value.id)
          if (index !== -1) {
            comments.value[index].content = editForm.value.content
            comments.value[index].updateTime = new Date().toISOString()
            
            // 更新缓存
            if (commentCache.value[editingComment.value.id]) {
              commentCache.value[editingComment.value.id].content = editForm.value.content
              commentCache.value[editingComment.value.id].updateTime = comments.value[index].updateTime
            }
          }
          
          // 取消编辑状态
          cancelEdit()
          ElMessage.success('评论已更新')
        } else {
          throw new Error(result?.message || '更新评论失败')
        }
      } catch (error) {
        console.error('更新评论失败:', error)
        ElMessage.error('更新评论失败，请稍后重试')
      }
    }
    
    // 删除评论
    const deleteCommentHandler = async (id) => {
      try {
        // 确认删除
        await ElMessageBox.confirm('确定要删除这条评论吗？', '删除确认', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        
        const result = await deleteComment(id)
        
        if (result && result.code === 200) {
          // 从本地列表移除
          comments.value = comments.value.filter(item => item.id !== id)
          // 从缓存中移除
          delete commentCache.value[id]
          
          // 更新总数
          total.value--
          emit('update:count', total.value)
          
          ElMessage.success('评论已删除')
        } else {
          throw new Error(result?.message || '删除评论失败')
        }
      } catch (error) {
        // 取消删除不提示错误
        if (error === 'cancel' || error.toString().includes('cancel')) {
          return
        }
        console.error('删除评论失败:', error)
        ElMessage.error('删除评论失败，请稍后重试')
      }
    }
    
    // 判断是否可以管理评论
    const canManageComment = (comment) => {
      const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
      return userInfo.id === comment.userId || userInfo.role === 3 // 自己的评论或管理员
    }
    
    onMounted(() => {
      fetchComments()
    })
    
    return {
      comments,
      loading,
      loadingMore,
      newComment,
      submitting,
      replyingTo,
      editingComment,
      editForm,
      sortType,
      hasMore,
      totalComments,
      sortedComments,
      defaultAvatar,
      fetchComments,
      loadMore,
      refresh,
      formatTime,
      handleVote,
      submitComment,
      replyTo,
      cancelReply,
      editComment,
      cancelEdit,
      submitEdit,
      deleteComment: deleteCommentHandler,
      canManageComment
    }
  }
}
</script>

<style scoped>
.comments-section {
  margin-top: 16px;
  padding: 16px;
  background-color: #f9f9f9;
  border-radius: 8px;
}

.comments-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.comments-title {
  font-weight: 600;
  font-size: 15px;
}

.comments-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.comments-loading {
  padding: 12px;
}

.comments-list {
  margin-bottom: 16px;
}

.comment-list-enter-active,
.comment-list-leave-active {
  transition: all 0.3s ease;
}

.comment-list-enter-from {
  opacity: 0;
  transform: translateY(20px);
}

.comment-list-leave-to {
  opacity: 0;
  transform: translateX(20px);
}

.comment-item {
  display: flex;
  padding: 12px;
  margin-bottom: 10px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  transition: all 0.2s ease;
}

.comment-item:hover {
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.comment-avatar {
  margin-right: 12px;
}

.comment-content {
  flex: 1;
}

.comment-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.comment-author {
  font-weight: 600;
  font-size: 14px;
  color: #333;
}

.comment-time {
  font-size: 12px;
  color: #8c8c8c;
}

.comment-body {
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  white-space: pre-wrap;
  word-break: break-word;
  margin-bottom: 8px;
}

.comment-edit {
  margin-bottom: 12px;
}

.edit-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
  gap: 8px;
}

.comment-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.comment-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* 新增点赞按钮样式 */
.vote-button {
  display: flex;
  align-items: center;
  cursor: pointer;
  padding: 2px 8px;
  border-radius: 12px;
  background-color: #f5f5f5;
  transition: all 0.2s ease;
}

.vote-button:hover {
  background-color: #e8f4ff;
}

.vote-button i {
  margin-right: 4px;
  font-size: 16px;
  color: #909399;
}

.vote-count {
  font-size: 14px;
  color: #606266;
}

.voted {
  background-color: #e8f4ff;
}

.voted i {
  color: #1890ff;
}

.voted .vote-count {
  color: #1890ff;
}

.action-btn {
  padding: 2px 8px;
  border-radius: 12px;
}

.action-btn:hover {
  background-color: #f5f5f5;
}

.no-comments {
  text-align: center;
  padding: 24px 0;
  color: #8c8c8c;
}

.load-more {
  text-align: center;
  margin-top: 12px;
}

.add-comment {
  margin-top: 20px;
  border-top: 1px solid #eee;
  padding-top: 16px;
}

.comment-input-header {
  font-size: 14px;
  margin-bottom: 8px;
  color: #333;
}

.comment-input-body {
  margin-bottom: 12px;
}

.comment-input-footer {
  display: flex;
  justify-content: flex-end;
}

/* 移动端适配 */
@media (max-width: 768px) {
  .comments-section {
    padding: 12px;
  }
  
  .comment-item {
    flex-direction: column;
  }
  
  .comment-avatar {
    margin-right: 0;
    margin-bottom: 8px;
  }
  
  .comment-header {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .comment-time {
    margin-top: 4px;
  }
}
</style> 